Rules for Tools/Tool Structure
The Tool Structure
When Bars&Pipes creates a Tool and plops it in a PipeLine, that instance of the Tool is
defined by a separate structure, the Tool structure. This carries all of the
information that is needed for this particular use of the Tool. When the `edittool()'
and `processevent()' routines are called, they work with this Tool. Each Tool is
composed of a kernel structure, the Tool structure, and any fields you might tag onto
the end for your particular Tool design. For example, a delay tool has a field that
determines by how many clock ticks to delay MIDI events. Here's the Tool structure, as
defined in `bars.h':
struct Tool {
struct Tool *next; /* Next tool used in Track. */
struct Tool *branch; /* Tool on other Track. */
struct Tool *parent; /* Parent tool (for macros.) */
struct ToolMaster *toolmaster;/* ToolMaster. */
struct Clip *clip; /* Clip to be worked on. */
struct String *name; /* Name of this tool. */
struct Window *window; /* Edit window. */
struct Track *track; /* Track that owns this tool. */
long toolid; /* Tool ID. */
unsigned short left,top; /* Position of edit window. */
unsigned short width,height;/* Size of edit window. */
unsigned short x,y; /* Position in pipe display. */
unsigned short xindex; /* How far down list this is. */
unsigned short yindex; /* How far down track list. */
short branchindex; /* How far away branch tool is. */
unsigned short id; /* ID for file io. */
char intool; /* True if in left PipeLine. */
char inedit; /* Indicates editing now. */
char touched; /* Initialization bits. */
char selected; /* Icon selected in graph? */
long tooltype; /* Sequence? Input? Branch? */ };
Here's an example Delay Tool that nests the Tool structure within it:
struct DelayTool {
struct Tool tool; /* Tool stuff. */
long delaytime; /* Delay time. */
};
Because the standard Tool structure is nested within DelayTool, Bars&Pipes can
access everything it needs to know about the Delay Tool, yet the Delay Tool can store
its additional information, the delay time, in the very same structure.
Here are definitions of the important Tool structure fields:
`next'
A pointer to the Tool that follows this Tool is placed in the
`next' field. This is the linkage that ties each PipeLine
together. When a Tool is finished processing an Event, it must
place the pointer to the next Tool in the Event so the Event can
be passed on properly.
`branch'
If the Tool is capable of sending Events to a Tool on another
PipeLine (Events sent to another pipeline are always sent to a
Merge In Tool,) `branch' holds a pointer to that Tool. Routing an
Event to the branching Tool is accomplished by placing that Tool,
rather than the next Tool in the PipeLine, into the Event
structure.
`toolmaster'
To access all of the generic information about a Tool, including
its name, image, and various routines, a pointer to the ToolMaster
structure that defines the Tool is stored in `toolmaster'.
`clip'
This is the Clip the Tool is currently working on. Although Tools
rarely touch the list of Events within the Clip, they may need to
refer to Song Parameters in the Clip. (For example, the Transpose
Tool uses the Key&Scale/Mode of the Clip to determine how to
tranpose a note within the Key.)
`touched'
When a Tool is first created, all of the special data fields that
you have defined (for example, the delay in clocks for a delay
Tool) are blank. At this point, touched is also blank. Two bits,
`TOUCH_EDIT' and `TOUCH_INIT' are set in `touched' once the data
fields are set, either by the user editing the Tool or by the Tool
itself when the first Event enters it. In the latter case, the
Tool always checks if either bit is set when an Event arrives to
see if the data fields are initialized. If they aren't, it does
the initialization and sets the `TOUCH_INIT' bit. See
Tool Touched Flags.